#ifndef	__RUNTIMECLASS_H__
#define	__RUNTIMECLASS_H__

#include "BasicType/BasicType.h"

namespace GCRE {
	namespace SceneModel {
	
		class IEntity;

		struct RuntimeClass {
			const BasicType::SFString m_strClassName;
			RuntimeClass* m_pBaseClass;
			RuntimeClass* m_pNextClass;
			IEntity* (*m_pfnCreateEntity)();

			static RuntimeClass* m_pFirstClass;
		};

		struct CLASSINIT {
			CLASSINIT( RuntimeClass* pNewClass )
			{
				pNewClass->m_pNextClass = RuntimeClass::m_pFirstClass;
				RuntimeClass::m_pFirstClass = pNewClass;
			}
		};

#define RUNTIME_CLASS( class_name )	\
	( &class_name::class##class_name )

#define DECLARE_DYNAMIC( class_name )	\
	public:	\
		static RuntimeClass class##class_name;	\
		virtual RuntimeClass* GetRuntimeClass() const;

#define _IMPLEMENT_RUNTIMECLASS( class_name, base_class_name, pfncreate )	\
	RuntimeClass class_name::class##class_name = \
		{ #class_name, RUNTIME_CLASS( base_class_name ), NULL, pfncreate };	\
		static CLASSINIT _init_##class_name( &class_name::class##class_name );	\
		RuntimeClass* class_name::GetRuntimeClass() const	\
		{ return &class_name::class##class_name; }

#define IMPLEMENT_DYNAMIC( class_name, base_class_name )	\
	_IMPLEMENT_RUNTIMECLASS( class_name, base_class_name, NULL )

#define DECLARE_DYNCREATE( class_name )	\
	DECLARE_DYNAMIC( class_name )	\
	static IEntity* CreateEntity();

#define IMPLEMENT_DYNCREATE( class_name, base_class_name )	\
	IEntity* class_name::CreateEntity() { return new class_name; }	\
	_IMPLEMENT_RUNTIMECLASS( class_name, base_class_name, class_name::CreateEntity )

	}
}

#endif	//	__RUNTIMECLASS_H__